package com.server;

import com.server.game.TransactionManager;
import com.server.game.logic.TickManager;
import com.server.net.message.MsgDispatcherManager;
import com.server.net.NettyProtobufServer;
import com.server.net.message.MsgProcessorManager;
import com.server.util.RedisUtil;
import com.server.orm.HibernateManager;
import com.server.util.ConfPropertiesUtil;
import com.server.util.LogUtil;

import java.util.concurrent.CountDownLatch;

/**
 * 使用阻塞的方式挂起线程，保证进程持续存在
 */
public class Server extends Thread {

    private CountDownLatch stopLatch = new CountDownLatch(1);//默认数值1，方便停止

    private NettyProtobufServer nettyProtobufServer = new NettyProtobufServer();

    private Thread shutdownHook;

    public void init(Thread shutdownHook) {
        this.shutdownHook = shutdownHook;
    }

    @Override
    public void run() {
        /**
         * 网络=netty+protobuf+缓冲管理
         * 表格=读取/更新+转换工具
         * 存储=数据映射框架+mysql+Hikari+redis+Jedis+合服工具+配置更新
         * 网关=SDK验证
         * 后台=订单系统+服务器管理+开关服控制+礼包/月卡/玩法控制
         * 基础=登录+下线+断线重连+全局榜单+场景管理+配置管理（linux+windows）+SDK接入
         * 推送=推送SDK接入+自定义推送逻辑
         */
        LogUtil.game.info("*********************服务器启动 开始***********************************");
        try {
            ConfPropertiesUtil.getInstance().init();//初始化配置
            LogUtil.game.info("服务器监听端口:" + ConfPropertiesUtil.getInstance()._PORT + "  DEBUG:" + ConfPropertiesUtil.getInstance()._DEBUG);
            LogUtil.game.info("协议处理线程数:" + ConfPropertiesUtil.getInstance()._MSG_THREAD_NUM);
            /*******************************************************************************/
            RedisUtil.init();//初始化redis链接
            HibernateManager.getInstance().init();//ORM
            MsgProcessorManager.getInstance().init("com.server.game.handler");//初始化协议处理
            TickManager.getInstance().init();//开启全局tick心跳
            MsgDispatcherManager.getInstance().init();//场景线程
            TransactionManager.getInstance().init();//开启Orm异步处理
        } catch (Exception e) {
            Runtime.getRuntime().removeShutdownHook(this.shutdownHook);
            LogUtil.game.error("Exception", e);
            System.exit(0);
        }
        LogUtil.game.info("*********************服务器启动 完成***********************************");
        /**
         * 不用while(true) { Thread.sleep(1000); } 阻塞线程
         * CountDownLatch虽然也是死循环方式检测状态，但在底层阻塞，无法获取锁，不唤醒线程，消耗极小
         * 但也需注意，CountDownLatch只可减不可加
         * while(true)本质上执行了线程，占用cpu资源
         */
        try {
            nettyProtobufServer.init();//开启netty服务
            this.stopLatch.await();
        } catch (InterruptedException e) {
            LogUtil.game.error("Exception", e);
        }
    }

    public void close() {
        MsgProcessorManager.getInstance().close();//停止协议接收及处理
        TickManager.getInstance().close();//全局tick停止
        MsgDispatcherManager.getInstance().close();//停止所有scene的处理

        TransactionManager.getInstance().close();//停止所有orm执行内容
        HibernateManager.close();//强制hibernate写库
        RedisUtil.close();//关闭redis链接
        this.stopLatch.countDown();
    }
}
